package cn.com.http.httpheader;

public class NetUrl {
	private boolean absolute = false;

	private String protocol = null;

	private String host = null;

	private int port = -1;

	private String path = null;

	private String query = "";

	private String fragment = "";

	private NetUrl() {

	}

	public NetUrl(String url) {
		int indexBegin = 0;
		int indexEnd = url.length();

		// Fragment.
		int indexFragment = url.lastIndexOf('#');
		if (indexFragment != -1) {
			this.fragment = url.substring(indexFragment + 1, indexEnd);
			indexEnd = indexFragment;
		}

		// Query
		int indexQuery = url.indexOf('?');
		if (indexQuery != -1 && indexQuery < indexEnd) {
			this.query = url.substring(indexQuery + 1, indexEnd);
			indexEnd = indexQuery;
		}

		// Protocol
		int indexProtocol = url.indexOf("://");
		if (indexProtocol != -1 && indexProtocol < indexEnd) {
			absolute = true;
			this.protocol = url.substring(indexBegin, indexProtocol);
			indexBegin = indexProtocol + 3;

			// Host
			int indexPath = url.indexOf('/', indexBegin);
			if (indexPath == -1)
				indexPath = indexEnd;

			// Port
			this.port = 80;
			int indexPort = url.indexOf(':', indexBegin);
			if (indexPort != -1 && indexPort < indexPath) {
				if (indexPort + 1 < indexPath) {
					this.port = Integer.parseInt(url.substring(indexPort + 1,
							indexPath));
				}
			} else {
				indexPort = indexPath;
			}

			// Host
			this.host = url.substring(indexBegin, indexPort);
			indexBegin = indexPath;
		}

		// Host & Port
		if (indexFragment == -1 && indexQuery == -1 && indexProtocol == -1) {
			int indexSlash = url.indexOf('/');
			if (indexSlash == -1) {
				int indexPort = url.indexOf(':', indexBegin);
				if (indexPort != -1) {
					this.host = url.substring(indexBegin, indexPort);
					this.port = Integer.parseInt(url.substring(indexPort + 1,
							indexEnd));
					indexEnd = indexBegin;
				}
			}
		}

		// Path
		if (indexBegin < indexEnd) {
			this.path = new String(url.substring(indexBegin, indexEnd));
		} else {
			this.path = null;
		}
	}

	public String getProtocol() {
		return protocol;
	}

	public String getHost() {
		return host;
	}

	public int getPort() {
		return port;
	}

	public String getPath() {
		return path;
	}

	public String getQuery() {
		return query;
	}

	public String getFragment() {
		return fragment;
	}

	public String getDirectory() {
		int indexSlash = path.lastIndexOf('/');
		if (indexSlash == -1)
			return null;
		return path.substring(0, indexSlash + 1);
	}

	public void setProtocol(String protocol) {
		if (protocol == null)
			throw new NullPointerException();
		this.protocol = protocol;
	}

	public void setPort(int port) {
		if (port < 1)
			throw new IllegalArgumentException();
		this.port = port;
	}

	public void setPath(String path) {
		if (path == null)
			throw new NullPointerException();
		this.path = path;
	}

	public void setQuery(String query) {
		if (query == null)
			throw new NullPointerException();
		this.query = query;
	}

	public void setFragment(String fragment) {
		if (fragment == null)
			throw new NullPointerException();
		this.fragment = fragment;
	}

	public boolean isAbsolute() {
		return absolute;
	}

	public void setAbsolute(boolean absolute) {
		if (protocol == null)
			throw new IllegalArgumentException(
					"URL cannot be absolute without a protocol: " + toString());

	}
}
